﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Windows.Forms.DataVisualization.Charting;

namespace MarketFunds
{
    public partial class frmMarketFunds : Form
    {
        
        private double dHSTotalData = -1;
        public frmMarketFunds()
        {
            InitializeComponent();
            
        }
        private void LoadFundsData()
        {
            
            //以下是主力大单的数据明细
            string strURL = "http://push2.eastmoney.com/api/qt/stock/fflow/kline/get?cb=jQuery112306505134490836288_1627469745078&lmt=0&klt=1&fields1=f1%2Cf2%2Cf3%2Cf7&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61%2Cf62%2Cf63%2Cf64%2Cf65&ut=b2884a393a59ad64002292a3e90d46a5&secid=1.000001&secid2=0.399001&_=1627469745079";

            string strText = HttpUtil.Get(strURL);
            //string[] rst = Regex.Split(strText, "klines\":[\"", RegexOptions.IgnoreCase);
            string[] rst = strText.Split(new string[1] { "klines\":[\"" }, System.StringSplitOptions.None);
            if (rst.Count() <= 1)
            {
                //MessageBox.Show("无法正确解析数据!");
                return;
            }
            string strBody = rst[1];
            string[] rst2 = Regex.Split(strBody, "\"]}}", RegexOptions.IgnoreCase);
            strBody = rst2[0];


            string[] rstData = Regex.Split(strBody, "\",\"", RegexOptions.IgnoreCase);
            for (int i = 0; i < rstData.Count(); i++)
            {
                // Console.WriteLine(rstData[i]);

                //2021-07-28 15:00,-62829493083.0,58280625928.0,4548867215.0,-33085619784.0,-29743873299.0
                string[] rstFunds = Regex.Split(rstData[i], ",", RegexOptions.IgnoreCase);
                if (rstFunds.Count() != 6)
                    continue;
                string strTime = rstFunds[0];
                double d主力净流入 = Convert.ToDouble(rstFunds[1]);
                double d超大单净流入 = Convert.ToDouble(rstFunds[5]);
                double d大单净流入 = Convert.ToDouble(rstFunds[4]);
                double d中单净流入 = Convert.ToDouble(rstFunds[3]);
                double d小单净流入 = Convert.ToDouble(rstFunds[2]);
                double dTotal = d主力净流入 + + d超大单净流入+ d大单净流入 + d中单净流入 + d小单净流入;

                ListViewItem itm = lvwReport.Items.Add(strTime);
                itm.SubItems.Add(d主力净流入.ToString("###,###.##")) ;
                itm.SubItems[1].Tag = d主力净流入;
                itm.SubItems.Add(d超大单净流入.ToString("###,###.##")) ;
                itm.SubItems[2].Tag = d超大单净流入;
                itm.SubItems.Add(d大单净流入.ToString("###,###.##") );
                itm.SubItems[3].Tag = d大单净流入;
                itm.SubItems.Add(d中单净流入.ToString("###,###.##") );
                itm.SubItems[4].Tag = d中单净流入;
                itm.SubItems.Add(d小单净流入.ToString("###,###.##") );
                itm.SubItems[5].Tag = d小单净流入;
                itm.SubItems.Add(dTotal.ToString("###,###.##"));
                itm.SubItems.Add("");

            }
            lvwReport.EnsureVisible(lvwReport.Items.Count - 1);
            for (int i = lvwReport.Items.Count - 1; i > 0; i--)
            {
                string strTotal2 = lvwReport.Items[i].SubItems[6].Text;
                string strTotal1 = lvwReport.Items[i - 1].SubItems[6].Text;
                if (strTotal1.Trim().Length == 0 || strTotal2.Trim().Length == 0)
                    continue;
                double dTotal2 = Convert.ToDouble(strTotal2);
                double dTotal1 = Convert.ToDouble(strTotal1);
                double dDiff = (dTotal2 - dTotal1) / Math.Abs(dTotal1);
                lvwReport.Items[i].SubItems[7].Text = dDiff.ToString("P");
            }

                for (int i = lvwReport.Items.Count - 1; i > 0; i--)
                {
                    double d主力1= (double)lvwReport.Items[i].SubItems[1].Tag;  //
                    double d主力2 = (double)lvwReport.Items[i - 1].SubItems[1].Tag;
                    double dDiff = (d主力1 - d主力2); //获得前一个时间的主力与后一个时间主力差值                                    
                    double dDiffPercent = dDiff / Math.Abs(d主力2); //当前差额与前一值的百分比
                    if (dDiff > 0 )
                    {
                        lvwReport.Items[i].ForeColor = Color.Red;
                        lvwReport.Items[i].SubItems[1].Text = lvwReport.Items[i].SubItems[1].Text + " ↑ " + dDiff.ToString("###,###.##") + " " + dDiffPercent.ToString("P");
                        //lvwReport.Items[i].BackColor = Color.HotPink;
                    }                    
                    else
                    {
                        lvwReport.Items[i].ForeColor = Color.Green;
                        lvwReport.Items[i].SubItems[1].Text = lvwReport.Items[i].SubItems[1].Text + " ↓" + dDiff.ToString("###,###.##") + " " + dDiffPercent.ToString("P");
                        //lvwReport.Items[i].BackColor = Color.Green;
                    }
                    if (dDiff < -8 * 100000000)  //如果一次性主力跑出8个亿，则报警 
                    {
                        string strHint = DateTime.Now.ToShortTimeString() + " 大盘主力资金发生异动流出,流出额达到 " +dDiff.ToString("###,###.##");
                        //将 hint送进后台处理线程，让线程给提示
                        AddHint(strHint);
                    }
    
                /////////////////////////////////////////////////////////////////////////////////
                    double d超大单1 = (double)lvwReport.Items[i].SubItems[2].Tag;  //
                    double d超大单2 = (double)lvwReport.Items[i - 1].SubItems[2].Tag;
                    dDiff = (d超大单1 - d超大单2); //获得前一个时间的主力与后一个时间主力差值                
                    if (dDiff > 0)
                        lvwReport.Items[i].SubItems[2].Text = lvwReport.Items[i].SubItems[2].Text + " ↑ " + dDiff.ToString("###,###.##");
                    else
                        lvwReport.Items[i].SubItems[2].Text = lvwReport.Items[i].SubItems[2].Text + " ↓" + dDiff.ToString("###,###.##"); ;
                    /////////////////////////////////////////////////////////////////////////////////
                    double d大单1 = (double)lvwReport.Items[i].SubItems[3].Tag;  //
                    double d大单2 = (double)lvwReport.Items[i - 1].SubItems[3].Tag;
                    dDiff = (d大单1 - d大单2); //获得前一个时间的主力与后一个时间主力差值                
                    if (dDiff > 0)
                        lvwReport.Items[i].SubItems[3].Text = lvwReport.Items[i].SubItems[3].Text + " ↑ " + dDiff.ToString("###,###.##");
                    else
                        lvwReport.Items[i].SubItems[3].Text = lvwReport.Items[i].SubItems[3].Text + " ↓" + dDiff.ToString("###,###.##"); ;
                    /////////////////////////////////////////////////////////////////////////////////
                    /////////////////////////////////////////////////////////////////////////////////
                    double d中单1 = (double)lvwReport.Items[i].SubItems[4].Tag;  //
                    double d中单2 = (double)lvwReport.Items[i - 1].SubItems[4].Tag;
                    dDiff = (d中单1 - d中单2); //获得前一个时间的主力与后一个时间主力差值                
                    if (dDiff > 0)
                        lvwReport.Items[i].SubItems[4].Text = lvwReport.Items[i].SubItems[4].Text + " ↑ " + dDiff.ToString("###,###.##");
                    else
                        lvwReport.Items[i].SubItems[4].Text = lvwReport.Items[i].SubItems[4].Text + " ↓" + dDiff.ToString("###,###.##"); ;
                    /////////////////////////////////////////////////////////////////////////////////
                    double d小单1 = (double)lvwReport.Items[i].SubItems[5].Tag;  //
                    double d小单2 = (double)lvwReport.Items[i - 1].SubItems[5].Tag;
                    dDiff = (d小单1 - d小单2); //获得前一个时间的主力与后一个时间主力差值                
                    if (dDiff > 0)
                        lvwReport.Items[i].SubItems[5].Text = lvwReport.Items[i].SubItems[5].Text + " ↑ " + dDiff.ToString("###,###.##");
                    else
                        lvwReport.Items[i].SubItems[5].Text = lvwReport.Items[i].SubItems[5].Text + " ↓" + dDiff.ToString("###,###.##"); ;
                    /////////////////////////////////////////////////////////////////////////////////
            }
            lvwReport.Columns[0].Width = -1;
            lvwReport.Columns[1].Width = -1;
            for (int i = 2; i < lvwReport.Columns.Count; i++)
            {
                lvwReport.Columns[i].Width = 0;
            }
            lvwNorth.Columns[0].Width = -1;
            lvwNorth.Columns[1].Width = -1;

        }
        private void LoadHSTotalData()
        {
            //以下是获得沪深股市总交易额的接口
            //http://push2.eastmoney.com/api/qt/ulist.np/get?cb=jQuery1123035870092396224695_1627480496552&fltt=2&secids=1.000001%2C0.399001&fields=f1%2Cf2%2Cf3%2Cf4%2Cf6%2Cf12%2Cf13%2Cf104%2Cf105%2Cf106&ut=b2884a393a59ad64002292a3e90d46a5&_=1627480496553

            /*
             * jQuery1123035870092396224695_1627480496552({"rc":0,"rt":11,"svr":182482182,"lt":1,"full":1,"data":{"total":2,"diff":[{"f1":2,"f2":3361.59,"f3":-0.58,"f4":-19.59,"f6":564697718784.0,"f12":"000001","f13":1,"f104":423,"f105":1536,"f106":35},{"f1":2,"f2":14086.42,"f3":-0.05,"f4":-7.22,"f6":705288294400.0,"f12":"399001","f13":0,"f104":517,"f105":1960,"f106":23}]}});
             * 根据既定的DOM类来分析即可，暂时用不到
             */
            string strURL = "http://push2.eastmoney.com/api/qt/ulist.np/get?cb=jQuery1123035870092396224695_1627480496552&fltt=2&secids=1.000001%2C0.399001&fields=f1%2Cf2%2Cf3%2Cf4%2Cf6%2Cf12%2Cf13%2Cf104%2Cf105%2Cf106&ut=b2884a393a59ad64002292a3e90d46a5&_=1627480496553";
            //打开JSON代码,先解析第一个页面
            string strJSON = string.Empty;
            strJSON = HttpUtil.Get(strURL);
            HSJSON json = new HSJSON();
            strJSON = json.GetPureHSJSON(strJSON);
            if (strJSON.Trim().Length == 0)
            {
                Console.Write("无数据或者解析出错!");
                Console.ReadLine();
                return;
            }
            this.dHSTotalData = json.GetHSTotalDataByJSON(strJSON);
            
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            StockExcel.CommonUtil.init();
            lvwReport.Columns[0].Width = 130;
            lvwReport.Columns[7].Width = 110;
            for (int i = 1; i <= 6; i++)
            {
                lvwReport.Columns[i].Width = 270;
            }
            for (int i = 2; i < lvwReport.Columns.Count; i++)
            {
                lvwReport.Columns[i].Width = 0;
            }
            lvwReport.Width = this.Width / 3;
            lvwNorth.Width = this.Width / 4;
            
            this.Text = "大盘主力情绪探测平台 V2.1";

            LoadMarketFundsHistory();
            ShowChart(1);
            ////////////
            StockExcel.CommonUtil.g_lstHint = new List<string>();
            if (StockExcel.CommonUtil.g_frmHint == null)
            {
                StockExcel.CommonUtil.g_frmHint = new StockExcel.frmHint();
                StockExcel.CommonUtil.g_frmHint.Text = "主力大盘情绪资金异动";
            }
            TimerFunds.Enabled = true;
            timerHintMonitor.Enabled = true;
        }
        /// <summary>
        /// 默认是装载主力资金，nType = 1 主力资金，2 = 北向资金，3 = 大盘交易量
        /// </summary>
        /// <param name="nType"></param>
        private void ShowChart(int nType = 1)
        {

            chart1.Series[0].Points.Clear();
            chart1.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            chart1.Series[0].BorderColor = Color.Red;
            //chart1.Series[0].BorderWidth = 15;
            //chart1.Series[0].ShadowOffset = 15;
            chart1.Series[0].BorderWidth = 3;
            chart1.ChartAreas[0].AxisX.Title = "日期";
            //chart1.ChartAreas[0].AxisY.Title = "金额(亿)";
            if (nType == 1)  
            {                
                for (int i = lvwHistory.Items.Count -1; i>= 0; i --)
                {
                    ListViewItem itm = lvwHistory.Items[i];
                    DateTime dt = (DateTime) itm.SubItems[0].Tag;
                    int nZL = (int)itm.SubItems[2].Tag;                
                    chart1.Series[0].Points.AddXY(dt,nZL);                   
                }
            }
            else if (nType == 2)
            {
                for (int i = lvwHistory.Items.Count - 1; i >= 0; i--)
                {
                    ListViewItem itm = lvwHistory.Items[i];
                    DateTime dt = (DateTime)itm.SubItems[0].Tag;
                    int nZL = (int)itm.SubItems[3].Tag;
                    chart1.Series[0].Points.AddXY(dt, nZL);
                }
            }
            else
            {
                for (int i = lvwHistory.Items.Count - 1; i >= 0; i--)
                {
                    ListViewItem itm = lvwHistory.Items[i];
                    DateTime dt = (DateTime)itm.SubItems[0].Tag;
                    int nZL = (int)itm.SubItems[1].Tag;
                    chart1.Series[0].Points.AddXY(dt, nZL);
                }
            }
        }
        /// <summary>
        /// 装载A股成交量历史数据
        /// </summary>
        private void LoadMarketFundsHistory()
        {
            string strSql = "select * from MarketFundsHistory order by hddate desc";
            OleDbCommand cmd = new OleDbCommand(strSql, StockExcel.CommonUtil.dbconn);
            OleDbDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                DateTime dt = (DateTime)reader["hddate"];
                ListViewItem itm = lvwHistory.Items.Add(dt.ToShortDateString());
                itm.SubItems[0].Tag = dt; 

                double dValue = (double)reader["MarketFunds"];
                itm.SubItems.Add(dValue.ToString("###,###.##"));
                int nMarket = (int)dValue ;
                itm.SubItems[1].Tag = nMarket;

                double dZL = (double)reader["ZLFunds"];                
                itm.SubItems.Add(dZL.ToString("###,###.##"));
                int nZL = (int)dZL;
                itm.SubItems[2].Tag = nZL;

                double dNorth = (double)reader["NorthFunds"];
                itm.SubItems.Add(dNorth.ToString("###,###.##"));
                int nNorth = (int)dNorth ;
                itm.SubItems[3].Tag = nNorth;

            }
            reader.Close();
            cmd.Dispose();
            /*
            for (int i = 0; i < lvwHistory.Columns.Count; i++)
            {
                lvwHistory.Columns[i].Width = -1;
            }
            */
        }
        private void TimerFunds_Tick(object sender, EventArgs e)
        {
            
            TimerFunds.Interval = 60 * 1000; //2分钟 ，120秒
            TimerFunds.Enabled = false;
            if (StockExcel.CommonUtil.IsInTradingTime())
            {
                lvwReport.Items.Clear();
                LoadHSTotalData();
                LoadFundsData();                                
                LoadNorthTotalData();
                textBox1.Text = (this.dHSTotalData / 100000000).ToString("###,###.##") + " 亿";
                WriteMarketFundsHistory(this.dHSTotalData);
                Show主力和北向();
            }
            
            TimerFunds.Enabled = true;
        }
        /// <summary>
        /// 把沪深交易额写到数据表MarketFundsHistory
        /// </summary>
        /// <param name="HSTotal"></param>
        private void WriteMarketFundsHistory(double HSTotal)
        {
            DateTime dToday = DateTime.Now;
            string strSql = "update MarketFundsHistory set MarketFunds=" + HSTotal/100000000 + " where hddate=#" + dToday.ToShortDateString()+"#";

            OleDbCommand cmd = new OleDbCommand(strSql,StockExcel.CommonUtil.dbconn);
            int n = cmd.ExecuteNonQuery();
            if (n <= 0)
            {
                //插入一条语句 
                strSql = "insert into MarketFundsHistory (hddate,MarketFunds) values (#" + dToday.ToShortDateString() + "# ," +
                     HSTotal/100000000 + ")";
                OleDbCommand cmd2 = new OleDbCommand(strSql, StockExcel.CommonUtil.dbconn);
                cmd2.ExecuteNonQuery();
                cmd2.Dispose();
            }
            cmd.Dispose();
        }
        /// <summary>
        /// 
        /// 写入当日主力和北向数据
        /// </summary>
        /// <param name="dZL"></param>
        /// <param name="dNorth"></param>
        private void WriteZLAndNorth(double dZL , double dNorth)
        {
            DateTime dToday = DateTime.Now;
            string strSql = "update MarketFundsHistory set ZLFunds=" + dZL / 100000000 + " ,NorthFunds="+ dNorth / 100000000 + " where hddate=#" + dToday.ToShortDateString() + "#";
            OleDbCommand cmd = new OleDbCommand(strSql, StockExcel.CommonUtil.dbconn);
            cmd.ExecuteNonQuery();            
            cmd.Dispose();
        }
        private void Show主力和北向()
        {
            if (lvwReport.Items.Count == 0)
            {                
                txtZL.Text = "";
                return;
            }
            if (lvwNorth.Items.Count == 0)
            {
                txtNorth.Text = "";
                return;
            }
            ListViewItem itmZL = lvwReport.Items[lvwReport.Items.Count - 1];
            double dZL = (double)itmZL.SubItems[1].Tag;
            ListViewItem itmNorth = lvwNorth.Items[lvwNorth.Items.Count - 1];
            double dNorth = (double)itmNorth.Tag;

            txtNorth.Tag = dNorth;
            txtZL.Tag = dZL;
            txtNorth.Text = (dNorth / 100000000).ToString("###,###.##") +" 亿";
            txtZL.Text = (dZL / 100000000).ToString("###,###.##") + " 亿";
            WriteZLAndNorth(dZL, dNorth);
        }
        /// <summary>
        /// 装载北向汇总数据
        /// </summary>
        private void LoadNorthTotalData()
        {
            NorthTotalJSON json = new NorthTotalJSON();
            string strURL = "https://datacenter-web.eastmoney.com/api/data/v1/get?callback=jQuery112308743243624904344_1658806388798&reportName=RPT_MUTUAL_QUOTA&columns=TRADE_DATE%2CMUTUAL_TYPE%2CBOARD_TYPE%2CMUTUAL_TYPE_NAME%2CFUNDS_DIRECTION%2CINDEX_CODE%2CINDEX_NAME%2CBOARD_CODE&quoteColumns=status~07~BOARD_CODE%2CdayNetAmtIn~07~BOARD_CODE%2CdayAmtRemain~07~BOARD_CODE%2CdayAmtThreshold~07~BOARD_CODE%2Cf104~07~BOARD_CODE%2Cf105~07~BOARD_CODE%2Cf106~07~BOARD_CODE%2Cf3~03~INDEX_CODE~INDEX_f3%2CnetBuyAmt~07~BOARD_CODE&quoteType=0&pageNumber=1&pageSize=200&sortTypes=1&sortColumns=MUTUAL_TYPE&source=WEB&client=WEB&_=1658806388799";
            string strJSON = string.Empty;
            strJSON = HttpUtil.Get(strURL);            
            strJSON = json.GetPureNorthTotalJSON(strJSON);
            if (strJSON.Trim().Length == 0)
            {
                Console.Write("无数据或者解析出错!");
                Console.ReadLine();
                return;
            }
            json.GetNorthTotalByJSON(strJSON);
            if (json.NorthTotalRoot.result.data.Count != 4)
                return;
            ListViewItem itm = lvwNorth.Items.Add(DateTime.Now.ToShortTimeString());
            double d沪股通 = Convert.ToDouble(json.NorthTotalRoot.result.data[0].netBuyAmt);
            double d深股通 = Convert.ToDouble(json.NorthTotalRoot.result.data[2].netBuyAmt);
            double dTotal = (d沪股通 + d深股通) * 10000;  //以万为单位
            itm.Tag = (double)dTotal;
            itm.SubItems.Add(dTotal.ToString("###,###.##"));
            
            if (lvwNorth.Items.Count == 1)
                return;
            for (int i = 1; i < lvwNorth.Items.Count; i++)
            {
                ListViewItem itmData2 = lvwNorth.Items[i];
                ListViewItem itmData1 = lvwNorth.Items[i - 1];
                double d1 = (double)itmData1.Tag;
                double d2 = (double)itmData2.Tag;
                double dDiff = (d2 - d1);
                if (dDiff > 0)
                {
                    lvwNorth.Items[i].ForeColor = Color.Red;
                    itmData2.SubItems[1].Text = d2.ToString("###,###.##") + " ↑ " + dDiff.ToString("###,###.##");
                }
                else
                {
                    lvwNorth.Items[i].ForeColor = Color.Green;
                    itmData2.SubItems[1].Text = d2.ToString("###,###.##") + " ↓ " + dDiff.ToString("###,###.##");
                }
                
            }
            lvwNorth.Columns[0].Width = -1;
            lvwNorth.Columns[1].Width = -1;
            lvwNorth.EnsureVisible(lvwNorth.Items.Count - 1);

        }
        private void 数据写入CSVToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            ListView lvw = (ListView)contextMenuStrip1.SourceControl;
            
            
            string strFileName = "大盘主力数据_" + DateTime.Now.ToString("yyyy-MM-dd") + ".csv";
            StockExcel.CommonUtil.WriteListViewDataToCSV(strFileName, lvw);
        }
        /// <summary>
        /// 添加提示信息
        /// </summary>
        /// <param name="strHint"></param>
        private void AddHint(string strHint)
        {
            bool bFind = false;
            for (int i = 0; i <StockExcel.CommonUtil.g_lstHint.Count; i++)
            {
                string strLine = (string)StockExcel.CommonUtil.g_lstHint[i];
                if (strLine == strHint)
                {
                    bFind = true;
                    StockExcel.CommonUtil.g_bAddHints = true;
                    break;
                }
            }
            if (!bFind)
            {
                StockExcel.CommonUtil.g_lstHint.Add(strHint);
                StockExcel.CommonUtil.g_bAddHints = false;
            }
        }

        private void timerHintMonitor_Tick(object sender, EventArgs e)
        {
            timerHintMonitor.Enabled = false;
            if (!StockExcel.CommonUtil.g_bAddHints)
            {
                timerHintMonitor.Enabled = true;
                return;
            }
            /*
             * 有了g_baddHInts信号，说明有新的警告，所以需要弹出窗口
             */
            if (StockExcel.CommonUtil.g_frmHint == null)
            {
                StockExcel.CommonUtil.g_frmHint = new StockExcel.frmHint();
            }
            StockExcel.CommonUtil.g_frmHint.m_lstHint = StockExcel.CommonUtil.g_lstHint;

            StockExcel.CommonUtil.g_frmHint.Show();
            StockExcel.CommonUtil.g_frmHint.ShowHint();
            StockExcel.CommonUtil.g_bAddHints = false;
            timerHintMonitor.Enabled = true;
        }

        private void 装载主力图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowChart(1);
        }

        private void 装载北向图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowChart(2);
        }

        private void 装载大盘交易量图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowChart(3);
        }

        private void 测试ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmMarketFunds2 frm = new frmMarketFunds2();
            frm.Show();
        }
    }
}
